package edu.indiana.cs.b534.torrent.impl;

import edu.indiana.cs.b534.torrent.TorrentException;
import edu.indiana.cs.b534.torrent.context.TorrentContext;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Logger;

/**
 * This class the TCP server and there is only one such server for a one client. When it received a
 * request, it create a new peer instance and ask it to handle the request 
 * @author hperera
 *
 */
public class BittorrentServer implements Runnable{
    private static Logger log = Logger.getLogger(TorrentManager.TORRENT_MANAGER_NAME);

	private ServerSocket severSocket;
	private TorrentContext torrentContext;
	private Thread thread;

    private TorrentManager torrentManager;

    public BittorrentServer(int port, TorrentManager torrentManager) throws TorrentException{
		try {
			severSocket = new ServerSocket(port);
			this.torrentContext = torrentManager.getTorrentContext();
            this.torrentManager = torrentManager;
            log.info("Server Started at port "+ port);
        } catch (IOException e) {
			throw new TorrentException(e);
		}
	}
	
    
    public void start(){
    	thread = new Thread(this);
    	thread.setDaemon(true);
    	thread.start();
    }
	
	public void run() {
		while(true){
			try {
				Socket client = severSocket.accept();
				log.info("Connection accepted from "+ client.getRemoteSocketAddress().toString());
				//We create a new Peer instance for new connection, start it and add it to the
				//incomming peer list
				PeerInstance peer = new PeerInstance(client.getInputStream(),client.getOutputStream(), torrentManager);
				Thread t = new Thread(peer);
				t.start();
				torrentContext.addPeer(peer, true);
			} catch (Exception e) {
				log.info("Falied while accepting a incomming connection "+ e.getMessage());
			}
		}
	}

}
